let ref = ['[object Map]', '[object Set]', '[object WeakMap]', '[object WeakSet]', '[object Date]', '[object RegExp]', '[object Error]']
const deepClone = function (obj,map = new WeakMap()) {
    /**使用WeakMap的理由？
     * WeakMap的key一定是一个对象的引用 且这是一种弱应用类型，不会影响垃圾回收机制
     * 对于深度拷贝可以有效的减少内存消耗
    **/
    let res = {}
    let type = Object.prototype.toString.call(obj)
    if(map.has(obj)){
        return map.get(obj)//不能返回 obj 使用存放在map中的值
    }
    if (type === '[object Object]') {
        map.set(obj,res)
        for (let key in obj) {
            if (Object.hasOwnProperty.call(obj,key)) {
                res[key] = deepClone(obj[key],map)
            }
        }
    } else if (type === '[object Array]') {
        res = []
        map.set(obj,res)//res会在后面的递归中获得填充
        obj.forEach((element, index) => {
            res[index] = deepClone(element,map)
        });
    } else if (ref.includes(type)) {
        res = new obj.constructor(obj)
    } else {
        res = obj
    }
    return res
}

const target = {
    field1: 1,
    field2: undefined,
    field3: {
        child: 'child'
        
    },
    field4: [2, 3, 8]
};
 target.target=target
 target.field4.push(target.field4)

let cloneTarget =deepClone(target)
target.field4.push(9)
console.log(target);
console.log(cloneTarget);